home *** CD-ROM | disk | FTP | other *** search
- (* :Title: Signal Processing Systems *)
-
- (* :Authors: Brian Evans, James McClellan *)
-
- (* :Summary: To provide system properties and definitions a la Myers. *)
-
- (* :Context: SignalProcessing`ObjectOriented`System` *)
-
- (* :PackageVersion: 2.7 *)
-
- (*
- :Copyright: Copyright 1989-1991 by Brian L. Evans
- Georgia Tech Research Corporation
-
- Permission to use, copy, modify, and distribute this software
- and its documentation for any purpose and without fee is
- hereby granted, provided that the above copyright notice
- appear in all copies and that both that copyright notice and
- this permission notice appear in supporting documentation,
- and that the name of the Georgia Tech Research Corporation,
- Georgia Tech, or Georgia Institute of Technology not be used
- in advertising or publicity pertaining to distribution of the
- software without specific, written prior permission. Georgia
- Tech makes no representations about the suitability of this
- software for any purpose. It is provided "as is" without
- express or implied warranty.
- *)
-
- (* :History: *)
-
- (* :Keywords: *)
-
- (*
- :Source: Myers, Cory. {Signal Representation for Symbolic and
- Numeric Processing}. M.I.T. Ph. D. Thesis. August,
- 1986. Appendix D.
-
- Covell, Michele. {An Algorithm Design Environment for
- Signal Processing}. M.I.T. Ph. D. Thesis. December,
- 1989.
- *)
-
- (* :Warning: *)
-
- (* :Mathematica Version: 1.2 or 2.0 *)
-
- (* :Limitation: *)
-
- (*
- :Discussion: Systems are defined in the same format as are mathematical
- operators. This format was chosen so that Mathematica's
- powerful pattern matcher could be used without adjustment.
- A full blown object representation was not needed since
- no cacheing, fetching, dynamic properties, etc. are needed
- as they are for signals. That is, a z-transform operator
- always exhibits linearity, and its properties do not
- change. In addition, systems are not instantiated as
- are signals.
-
- Properties are attached to the operator AND its parameters.
- If an operator can take optional arguments, then all flavors
- of it must be separately installed by DefineSystem.
- *)
-
- (*
- :Functions: ASSOCIATIVE
- ADDITIVE
- COMMUTATIVE
- CONTINUOUS
- DefineSystem
- DISCRETE
- HOMOGENEOUS
- LINEAR
- LINEARPHASE
- MEMORYLESS
- MoveOperatorsToFront
- SEPARABLE
- SHIFTINVARIANT
- SystemQ
- ValidOperatorQ
- *)
-
-
-
- (* B E G I N P A C K A G E *)
-
- BeginPackage[ "SignalProcessing`ObjectOriented`System`",
- "SignalProcessing`Support`FilterSupport`",
- "SignalProcessing`Support`SigProc`",
- "SignalProcessing`Support`SupCode`" ]
-
-
- If [ TrueQ[ $VersionNumber >= 2.0 ],
- Off[ General::spell ];
- Off[ General::spell1 ] ];
-
-
- (* U S A G E I N F O R M A T I O N *)
-
- ASSOCIATIVE::usage =
- "ASSOCIATIVE is a system property. \
- It also serves as a function. \
- ASSOCIATIVE[system] returns True if the system is associative. \
- Note that a system is a (parameterized) operator to which \
- DefineSystem has attached properties. \
- See also DefineSystem and SystemQ."
-
- ADDITIVE::usage =
- "ADDITIVE is a system property. \
- An operator T is additive if T[x + y] = T[x] + T[y] for all x, y. \
- It also serves as a function. \
- ADDITIVE[system] returns True if the operator system is additive. \
- Note that a system is a (parameterized) operator to which \
- DefineSystem has attached properties. \
- See also DefineSystem and SystemQ."
-
- COMMUTATIVE::usage =
- "COMMUTATIVE is a system property. \
- It also serves as a function. \
- COMMUTATIVE[system] returns True if the system is commutative. \
- Note that a system is a (parameterized) operator to which \
- DefineSystem has attached properties. \
- See also DefineSystem and SystemQ."
-
- CONTINUOUS::usage =
- "CONTINUOUS is a system property. \
- It also serves as a function. \
- CONTINUOUS[system] returns True if the operator system only takes \
- CONTINUOUS systems as arguments. \
- Note that a system is a (parameterized) operator to which \
- DefineSystem has attached properties. \
- See also DefineSystem and SystemQ."
-
- DefineSystem::usage =
- "DefineSystem[operator, property1, property2, ...] will install \
- the operator as a system. \
- The properties property1, property2, ... are considered to be True \
- for the operator. \
- For example, if DefineSystem[Upsample[l, n], DISCRETE, LINEAR] \
- is evaluated, Upsample will be added to the list of system operators \
- SPsystems, and one of the four rules generated is \
- CONTINUOUS[Shift[l,n]] := True. \
- Note that CONTINUOUS[Shift] will have no meaning."
-
- DISCRETE::usage =
- "DISCRETE is a system property. \
- It also serves as a function. \
- DISCRETE[system] returns True if the system only accepts \
- DISCRETE signals as arguments. \
- Note that a system is a (parameterized) operator to which \
- DefineSystem has attached properties. \
- See also DefineSystem and SystemQ."
-
- HOMOGENEOUS::usage =
- "HOMOGENEOUS is a system property. \
- An operator T is homogeneous if T[a x] = a T[x] if a is a scalar. \
- It also serves as a function. \
- HOMOGENEOUS[system] returns True if the system is homogeneous. \
- Note that a system is a (parameterized) operator to which \
- DefineSystem has attached properties. \
- See also DefineSystem and SystemQ."
-
- LINEAR::usage =
- "LINEAR is a system property. \
- A system is linear if it is both HOMOGENEOUS and ADDITIVE. \
- It also serves as a function. \
- LINEAR[system] returns True if the operator system is linear. \
- Note that a system is a (parameterized) operator to which \
- DefineSystem has attached properties. \
- See also DefineSystem and SystemQ."
-
- LINEARPHASE::usage =
- "LINEARPHASE is a system property. \
- A system exhibits linear phase if the phase component of its \
- frequency response is an affine function of the frequency. \
- It also serves a a function. \
- LINEARPHASE[system] returns True if the system is memoryless. \
- Note that a system is a (parameterized) operator to which \
- DefineSystem has attached properties. \
- See also DefineSystem and SystemQ."
-
- MEMORYLESS::usage =
- "MEMORYLESS is a system property. \
- A system is memoryless if each output corresponding to a given input \
- only depends on the input (and not past values of the input). \
- It also serves a a function. \
- MEMORYLESS[system] returns True if the system is memoryless. \
- Note that a system is a (parameterized) operator to which \
- DefineSystem has attached properties. \
- A MEMORYLESS system with a single input is also SHIFTINVARIANT. \
- See also DefineSystem and SystemQ."
-
- MoveOperatorsToFront::usage =
- "MoveOperatorsToFront[head_operator, signals, signals_to_move, \
- operator_to_move] will move all operator_to_move operators \
- contained in signals_to_move to the front of the expression formed \
- by the head_operator operating on signals. \
- For example, MoveOperatorsToFront[ Convolve[n], \
- { x[n], Shift[2,n][y[n]] }, { Shift[2,n][y[n]] }, Shift ] \
- yields Shift[2,n] [ Convolve[n] [ x[n], y[n] ] ]. \
- This is a valid rewriting of the original expression. \
- In this case, Convolve[n] [x[n], Shift[2,n][y[n]]]. \
- This object is used in the system rewrite rules to rewrite \
- properly an operator operating on more than one signal."
-
- SEPARABLE::usage =
- "SEPARABLE is a system property. \
- It describes multidimensional systems that can decomposed \
- into a cascade of one-dimensional operations. \
- It also serves as a function. \
- SEPARABLE[system] returns True if the \
- operator system is separable. \
- Note that a system is a (parameterized) operator to which \
- DefineSystem has attached properties. \
- See also DefineSystem and SystemQ."
-
- SHIFTINVARIANT::usage =
- "SHIFTINVARIANT is a system property. \
- It means that a shift in the input causes the same shift \
- in the output. \
- It also serves as a function. \
- SHIFTINVARIANT[system] returns True if the \
- operator system is shift-invariant. \
- Note that a system is a (parameterized) operator to which \
- DefineSystem has attached properties. \
- See also DefineSystem and SystemQ."
-
- SystemProperties::usage =
- "SystemProperties[system] will show the properties attached to \
- of an operator or list of operators. \
- Note that a system is a (parameterized) operator to which \
- DefineSystem has attached properties. \
- See also DefineSystem and SystemQ."
-
- SPsystems::usage =
- "SPsystems is a list of all recognized systems. \
- Note that a system is a (parameterized) operator to which \
- DefineSystem has attached properties. \
- New ones can be defined by using DefineSystem."
-
- SPproperties::usage =
- "SPproperties contains a list of currently recognized \
- system properties like LINEAR."
-
- SystemQ::usage =
- "SystemQ[system] will give True if system is in the SPsystems list, \
- and False otherwise. \
- Note that a system is a (parameterized) operator to which \
- DefineSystem has attached properties. \
- For example, by default, Shift[L, n] has been installed as a system, \
- but Shift without the parameters has not."
-
- ValidOperatorQ::usage =
- "ValidOperatorQ[system, signal1, signal2, ...] will return True \
- if every signal can be processed by the system. \
- For example, False would be returned if system was only a \
- discrete system and signal1 was a continuous signal."
-
- (* E N D U S A G E I N F O R M A T I O N *)
-
-
- Begin[ "`Private`" ]
-
-
- (* G L O B A L S *)
-
- SPsystems = {}
-
- ValidOperatorQ::incompatible =
- "The operator `` could not operate on one or more of these signals: ``."
-
- compatibilitycheck =
- "`1`/: `2`[inputs__] := \
- Message[ValidOperatorQ::incompatible, `3`, {inputs}] /; \
- ! ValidOperatorQ[`3`, inputs]"
-
- SPproperties =
- {ASSOCIATIVE, ADDITIVE, COMMUTATIVE, CONTINUOUS, DISCRETE,
- HOMOGENEOUS, LINEAR, LINEARPHASE, MEMORYLESS, SEPARABLE,
- SHIFTINVARIANT}
-
-
- (* S U P P O R T I N G R O U T I N E S *)
-
- (* DefineSystem -- generates Mathematica code for a system description *)
- (* abbreviations: op for operator, prop for property, tsd for TagSetDelay *)
-
- (*
- defproperty[prop_, op_, headop_] :=
- If [ AtomQ[op],
- TagSetDelayed[op, prop[op], True],
- TagSetDelayed[headop, prop[op], True];
- TagSetDelayed[headop, prop[headop], True] ]
- *)
-
- (* defproperty-- do not attach rules to Mathematica's built-in operators *)
- defproperty[prop_Symbol, headop_, headop_] :=
- Set[prop[headop], True] /;
- SameQ[Context[headop], "System`"]
- defproperty[prop_Symbol, op_, headop_] :=
- TagSetDelayed[prop, prop[op], True] /;
- SameQ[Context[headop], "System`"]
- defproperty[prop_Symbol, op_, headop_] :=
- TagSetDelayed[headop, prop[op], True]
-
- SetAttributes[DefineSystem, HoldFirst]
-
- DefineSystem[h_Symbol, properties__] :=
- definesystem[ h, h, h, h, properties ]
- DefineSystem[h_[args__], properties__] :=
- definesystem[ h,
- Apply[h, Map[ToString, {args}]],
- Apply[h, Map[GeneratePattern, {args}]],
- h[args],
- properties ]
-
- definesystem[headop_, opstr_, op_, fullop_, properties__] :=
- Block [ {proplist, protected, tsdattributes},
-
- protected = HasAttributes[headop, Protected];
- If [ protected, UnprotectIt[headop] ];
- proplist = ToList[properties];
-
- (* Defining rules for compatibility checking between *)
- (* signals and systems. This is only necessary when an *)
- (* operator takes only continuous signals or discrete *)
- (* signals as arguments. *)
- If [ Xor[MemberQ[proplist, DISCRETE],
- MemberQ[proplist, CONTINUOUS]],
- GenerateCode[
- StringForm[compatibilitycheck, headop,
- InputForm[op], InputForm[fullop]] ] ];
-
- (* TagSetDelayed needs to evaluate its arguments *)
- (* for the code generation to work. *)
- tsdattributes = Attributes[TagSetDelayed];
- Unprotect[TagSetDelayed];
- ClearAttributes[TagSetDelayed, {HoldFirst, HoldRest, HoldAll}];
-
- (* Establishes a property as an Mathematica operator *)
- (* which takes a system operator as an argument. *)
- (* This allows statements like DISCRETE[Upsample] and *)
- (* DISCRETE[Upsample[3,n]] to return True. *)
- If [ MemberQ[proplist, LINEAR],
- Combine[proplist, {ADDITIVE, HOMOGENEOUS}] ];
- Map [ defproperty[#1, op, headop]&, proplist ];
-
- (* Return TagSetDelayed to its original evaluation settings *)
- SetAttributes[TagSetDelayed, tsdattributes];
-
- (* Maintain a list of DSP operators *)
- Unprotect[SPsystems];
- Combine[SPsystems, {opstr}];
- Protect[SPsystems];
-
- (* Restore protection of the operator if set beforehand *)
- If [ protected, ProtectIt[headop] ];
-
- headop ]
-
- (* MoveOperatorToFront *)
- MoveOperatorsToFront[ op_, siglist_, sigleftlist_, optomove_ ] :=
- Block [ {numops, opindex, oplist, result},
- oplist = Map[OperatorInOperExpr, sigleftlist];
- numops = Length[oplist];
- result = Apply[op, Map[SignalsInOperExpr[#, optomove]&, siglist]];
- For [ opindex = 1, opindex <= numops, opindex++,
- result = oplist[[opindex]] [ result ] ];
- result ]
-
- (* SystemQ *)
- SystemQ[op_[args__]] := SystemQ[op]
- SystemQ[op_] := MemberQ[SPsystems, op] /; AtomQ[op]
-
- (* ValidOperatorQ *)
- ValidOperatorQ[system_, signal_] :=
- Which [ TrueQ[ DISCRETE[signal] ],
- TrueQ[ DISCRETE[system] ],
- TrueQ[ CONTINUOUS[signal] ],
- TrueQ[ CONTINUOUS[system] ],
- True,
- True ]
- ValidOperatorQ[system_, signal1_, signal__] :=
- And[ValidOperatorQ[system, signal1], ValidOperatorQ[system, signal]]
-
-
- (* R E C O G N I Z E D S Y S T E M S *)
-
- (* Standard Mathematica operators *)
-
- DefineSystem[Plus, COMMUTATIVE, CONTINUOUS, DISCRETE, MEMORYLESS]
- DefineSystem[Times, COMMUTATIVE, CONTINUOUS, DISCRETE, LINEAR, MEMORYLESS]
-
- (* Operators in the signal processing packages *)
-
- DefineSystem[CircularShift[n0, N, n], DISCRETE, LINEAR, SHIFTINVARIANT]
- DefineSystem[Conjugate,
- ADDITIVE, CONTINUOUS, DISCRETE, MEMORYLESS, SHIFTINVARIANT]
- DefineSystem[CConvolve[t],
- ASSOCIATIVE, COMMUTATIVE, CONTINUOUS, LINEAR, SHIFTINVARIANT]
- DefineSystem[Convolve[n],
- ASSOCIATIVE, COMMUTATIVE, DISCRETE, LINEAR, SHIFTINVARIANT]
- DefineSystem[Difference[k, n], DISCRETE, LINEAR, SEPARABLE]
- DefineSystem[Divide, CONTINUOUS, DISCRETE, MEMORYLESS]
- DefineSystem[Downsample[m, n], DISCRETE, LINEAR ]
- Downsample/: SEPARABLE[ Downsample[m_, n_List] ] := DiagonalMatrixQ[m]
- DefineSystem[DFT[l, n, k], DISCRETE, LINEAR]
- DefineSystem[DTFT[n, w], DISCRETE, LINEAR]
- DefineSystem[FIR[n, coeffs], DISCRETE, LINEAR, SHIFTINVARIANT]
- DefineSystem[FT[t, w], CONTINUOUS, LINEAR]
- DefineSystem[IIR[n, coeffs], DISCRETE, LINEAR, SHIFTINVARIANT]
- DefineSystem[Im,
- ADDITIVE, CONTINUOUS, DISCRETE, MEMORYLESS, SHIFTINVARIANT]
- DefineSystem[Interleave[n], DISCRETE]
- DefineSystem[InvDFT[l, k, n], DISCRETE, LINEAR]
- DefineSystem[InvDTFT[w, n], DISCRETE, LINEAR]
- DefineSystem[InvFT[w, t], CONTINUOUS, LINEAR]
- DefineSystem[InvL[s, t], CONTINUOUS, LINEAR]
- DefineSystem[InvZ[z, n], DISCRETE, LINEAR]
- DefineSystem[L[t, s], CONTINUOUS, LINEAR]
- DefineSystem[Periodic[k, n], CONTINUOUS, DISCRETE, SEPARABLE]
- DefineSystem[PolyphaseDownsample[m, h, n], DISCRETE, LINEAR]
- DefineSystem[PolyphaseUpsample[l, h, n], DISCRETE, LINEAR]
- DefineSystem[Re,
- ADDITIVE, CONTINUOUS, DISCRETE, MEMORYLESS, SHIFTINVARIANT]
- (* DefineSystem[Reciprocal, CONTINUOUS, DISCRETE, MEMORYLESS, SHIFTINVARIANT] *)
- DefineSystem[Rev[n], CONTINUOUS, DISCRETE, LINEAR, SEPARABLE]
- DefineSystem[ScaleAxis[l, w], CONTINUOUS, LINEAR, SEPARABLE]
- DefineSystem[Shift[l, n],
- CONTINUOUS, DISCRETE, LINEAR, SEPARABLE, SHIFTINVARIANT]
- DefineSystem[Subtract, CONTINUOUS, DISCRETE, MEMORYLESS]
- DefineSystem[Summation[i, ibeg, iend, inc], DISCRETE, LINEAR]
- DefineSystem[Upsample[l, n], DISCRETE, LINEAR]
- Upsample/: SEPARABLE[ Upsample[m_, n_List] ] := DiagonalMatrixQ[m]
- DefineSystem[Z[n, z], DISCRETE, LINEAR]
-
- (* Retrive the properties attached to an operator *)
-
- SetAttributes[SystemProperties, Listable]
-
- SystemProperties[op_] := ( op -> Select[ SPproperties, TrueQ[#1[op]]& ] )
-
-
- (* E N D P A C K A G E *)
-
- End[]
- EndPackage[]
-
- If [ TrueQ[ $VersionNumber >= 2.0 ],
- On[ General::spell ];
- On[ General::spell1 ] ];
-
-
- (* W R I T E P R O T E C T I O N *)
-
- Block [ {newfuns},
- newfuns = { DefineSystem, MoveOperatorsToFront, SystemQ,
- SystemProperties, ValidOperatorQ };
- Combine[ SPfunctions, newfuns ];
- Apply[ Protect, newfuns ] ]
-
-
- (* E N D I N G M E S S A G E *)
-
- Print["System definitions have been loaded."]
- Null
-